/*
 * @version: 1.0
 * @Date: 2022-03-20 13:35:04
 * @LastEditTime: 2022-03-21 11:36:11
 * @LastEditors: 牙叔
 * @Description: autojs起手式
 * @FilePath: \autojs起手式\main.js
 * @名人名言: 牙叔教程 简单易懂
 * @bilibili: 牙叔教程
 * @公众号: 牙叔教程
 * @QQ群: 747748653
 */
/* ---------------导入依赖--------------------------------------------------- */
var colors = require("colors");
const fs = require("fs");
const path = require("path");
const shell = require("shelljs");
const request = require("request");

let config = require("./config");
/* ---------------主逻辑----------------------------------------------------------- */
let projectName;
process.argv.forEach((val, index) => {
  // console.log(`${index}: ${val}`);
  if (index == 2) {
    projectName = val.trim();
  }
});
// 参数从第三个开始
// 0: D:\software\nodejs\node.exe
// 1: D:\script\myGit\autojs起手式\main.js
// 2: my-project

// let projectName = "my-project";
console.log("项目名称:", projectName);
if (!projectName || projectName.length < 2) {
  let info = "项目名称长度必须大于2, 创建项目命令: npm run create projectName";
  console.log(info.red);
  throw info;
}

if (/^\d/.test(projectName)) {
  console.log("项目名称不能以数字开头".red);
  throw "项目名称不能以数字开头";
}
if (!/^[a-zA-Z\d-_]*$/.test(projectName)) {
  console.log("项目名称只能包含数字字母下划线中划线".red);
  throw "项目名称只能包含数字字母下划线中划线";
}

// 检查当前目录中是否存在该文件。
let projectPath = path.join(config.projectFolder, projectName);
projectPath = path.normalize(projectPath);
projectPath = path.resolve(projectPath); // 绝对路径
main(projectName, projectPath);
/* ---------------自定义函数------------------------------------------------------- */
async function main(projectName, projectPath) {
  await accessFile(projectPath);
  await mkdir(projectPath);
  hasGit();
  cdPath(projectPath);
  gitClone(projectPath);
  mvFiles(projectPath);
  console.log("项目创建成功: " + projectPath);
  /* -------------------------------------------------------------------------- */
  if (config.associateRemoteRepository) {
    await associateRemoteRepository(projectName, projectPath);
  }
  openProject(projectPath);
}
function openProject() {
  shell.exec("code " + projectPath);
}
async function associateRemoteRepository(projectName, projectPath) {
  let ssh_url = await createRemoteRepository(projectName);
  console.log("ssh_url: ", ssh_url);
  setRepositoryUrlForProject(projectPath, ssh_url);
}
function setRepositoryUrlForProject(projectPath, ssh_url) {
  shell.cd(projectPath);
  console.log(process.cwd());
  let cmd = `git remote set-url origin ${ssh_url}`;
  console.log("cmd: ", cmd);
  if (shell.exec(cmd).code !== 0) {
    shell.echo("Error: Git remote set-url failed");
    shell.exit(1);
  }
}
function createRemoteRepository(projectName) {
  return new Promise((resolve, reject) => {
    var headers = {
      "Content-Type": "application/json;charset=UTF-8",
    };

    var dataString =
      '{"access_token":"' +
      config.token +
      '","name":"' +
      projectName +
      '","has_issues":"true","has_wiki":"true","can_comment":"true","private":"true"}';

    var options = {
      url: "https://gitee.com/api/v5/user/repos",
      method: "POST",
      headers: headers,
      body: dataString,
    };

    request(options, (error, response, body) => {
      if (error) {
        reject(error);
      }
      switch (response.statusCode) {
        case 201:
          console.log("创建远程仓库成功".green, projectName);
          let obj = JSON.parse(body);
          let ssh_url = obj.ssh_url;
          resolve(ssh_url);
          break;
        case 422:
          reject(("已存在同地址仓库（忽略大小写）, 请删除远程仓库, 或者换个项目名字" + projectName).red);
          break;
        default:
          reject("unknown statusCode");
          break;
      }
    });
  });
}
function cpOtherFiles(projectPath) {
  let otherFiles = config.otherFiles;
  shell.cd(projectPath);

  // let fromPath = "D:/script/商店脚本";
  // let toPath = "D:/script/myGit/otherFilesTestV1/references";
  // shell.mkdir("-p", toPath);

  otherFiles.forEach(function (fileData) {
    let toPath = path.join(projectPath, fileData.to);
    toPath = path.normalize(toPath);
    toPath = path.resolve(toPath); // 绝对路径

    // '-d', 'path': true if path is a directory
    // '-f', 'path': true if path is a regular file
    if (shell.test("-d", fileData.from)) {
      shell.cp("-rf", fileData.from, toPath);
    } else {
      shell.cp(fileData.from, toPath);
    }
  });
}
function mvFiles(projectPath) {
  let url = config.repositoryUrl;
  let data = path.parse(url);
  let base = data.base;
  shell.cd(base);
  shell.ls().forEach(function (file) {
    if (
      ~[
        "node_modules",
        "references",
        "package.json",
        "package-lock.json",
        "project.json",
        "push.js",
        "readme.md",
        "tsconfig.json",
      ].indexOf(file)
    ) {
      shell.mv(file, projectPath);
    }
  });
  shell.mv([".git", ".vscode", ".gitignore"], projectPath);
  shell.cd("..");
  console.log("删除文件夹: " + base);
  shell.rm("-rf", base);
  shell.touch("main.js");
  shell.ShellString('toastLog("公众号: 牙叔教程")').to("main.js");
  shell.ShellString("\n/references").toEnd(".gitignore");
}
function cdPath(filePath) {
  shell.cd(filePath);
}
function gitClone(filePath) {
  let url = config.repositoryUrl;
  console.log("url: " + url);
  // Run external tool synchronously
  console.log("开始下载仓库: " + url);
  let cmd = `git clone ${url}`;
  console.log("cmd: ", cmd);
  if (shell.exec(cmd).code !== 0) {
    shell.echo("Error: Git commit failed");
    shell.exit(1);
  }
  console.log("下载仓库成功: " + url + " 到 " + filePath);
}
function hasGit() {
  if (!shell.which("git")) {
    shell.echo("Sorry, this script requires git");
    shell.exit(1);
  }
}

function accessFile(filePath) {
  console.log("检查目录中是否存在该文件:", filePath);
  return new Promise((resolve, reject) => {
    fs.access(filePath, fs.constants.F_OK, (err) => {
      if (err) {
        console.log("文件夹不存在, 可以创建项目: " + projectName);
        resolve(filePath);
      } else {
        console.log(("文件夹已存在, 请修改项目名字或删除文件夹: " + filePath).red);
        reject(filePath);
      }
    });
  });
}
function mkdir(filePath) {
  console.log("创建文件夹: " + projectName);
  return new Promise((resolve, reject) => {
    fs.mkdir(filePath, (err) => {
      if (err) {
        console.log("创建文件夹失败: " + projectName);
        reject(err);
      }
      console.log("创建文件夹成功: " + projectName);
      resolve();
    });
  });
}
// // 创建 /tmp/a/apple 目录，无论是否存在 /tmp 和 /tmp/a 目录。
// fs.mkdir("./a/b/c/apple", { recursive: true }, (err) => {
//   if (err) throw err;
//   console.log("目录创建成功");
// });
